package com.jkt.rms.dataservice.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;

import com.jkt.rms.business.Resource;
import com.jkt.rms.commons.utils.RMSException;
import com.jkt.rms.dataservice.AbstractDataService;
import com.jkt.rms.dataservice.QueryConstants;
import com.jkt.rms.dataservice.ReportDataService;
import com.jkt.rms.vo.ReportVO;

public class ReportDataServiceImpl extends AbstractDataService<Resource>
		implements ReportDataService {

	@Override
	protected Class<Resource> getReferenceClass() {
		return Resource.class;
	}

	@SuppressWarnings("unchecked")
	public void getReportData() throws RMSException{
		Query qs = getSession().createSQLQuery(QueryConstants.QRY_RATE_RESOURCE);
		List<Object> s = qs.list();
		try {
			Set dataSet = getReportMap(s);
		} catch (ParseException e) {
			throw new RMSException("Parse Exception");
		}
		System.out.println("HAHA"+s.size());
	}
	
	@SuppressWarnings("unchecked")
	private Set getReportMap(List<Object> inList) throws ParseException{
		Iterator itr =  inList.iterator();
		Set set = new HashSet();
		while(itr.hasNext()){
			Object[] row = (Object[])itr.next();
			
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
			Date monthStDate = df.parse((String)row[0]);
			Date monthEndDate = df.parse((String)row[1]);
			Date prjStDate = (java.sql.Timestamp)row[4];
			Date prjEndDate = (java.sql.Timestamp)row[5];
			Date locationStDate = (java.sql.Timestamp)row[7];
			Date locationEndDate = (java.sql.Timestamp)row[8];
			Date roleStDate = (java.sql.Timestamp)row[10];
			Date roleEndDate = (java.sql.Timestamp)row[11];
			
			Date startDate = getMaxDate(monthStDate, prjStDate, locationStDate, roleStDate);
			Date endDate =  getMinDate(monthEndDate, prjEndDate, locationEndDate, roleEndDate);
			
			if(startDate.before(endDate)){
				for(Date d = startDate; d.compareTo(endDate) <= 0; d = getNextDate(d)){
					if(isSatSundayOrHoliday(d)){
						continue;
					}
					ReportVO rVO = new ReportVO();
					rVO.setResourceId((Integer)row[2]);
					rVO.setMonthDate(d);
					rVO.setLocationId((Integer)row[6]);
					rVO.setRate((BigDecimal)row[12]);
					System.out.println(rVO.toString());
					set.add(rVO);
				}
			}
			
			System.out.println(startDate +"  "+endDate+"  "+set.size());
		}
		return set;
	}
	
	private Date getMaxDate(Date... date){
		Date[] allDates = date;
		Date maxDate = null;
		if(allDates != null && allDates.length > 0){
			for (Date date2 : allDates) {
				if(maxDate == null){
					maxDate = date2;
				}
				if(maxDate.compareTo(date2) < 0){
					maxDate = date2;
				}
			}
		}
		return maxDate;
	}
	
	private Date getMinDate(Date... date){
		Date[] allDates = date;
		Date minDate = null;
		if(allDates != null && allDates.length > 0){
			for (Date date2 : allDates) {
				if(minDate == null){
					minDate = date2;
				}
				if(minDate.compareTo(date2) > 0){
					minDate = date2;
				}
			}
		}
		return minDate;
	}
	
	private Date getNextDate(Date date){
		int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
	    Date newDate = new Date(date.getTime() + MILLIS_IN_DAY);
	    return newDate;
	}
	
	private boolean isSatSundayOrHoliday(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		if(cal.get(Calendar.DAY_OF_WEEK) == 1 || cal.get(Calendar.DAY_OF_WEEK) == 7){
			return true;
		}
		return false;
	}

}
